﻿using System.Security;
using System.Threading;
using System.Web;
using BLL.Security;

namespace Web.Infrastructure.Security
{
    /// <summary>
    /// Use this class to build and assign <see cref="MultilevelPrincipal"/> instance to the http
    /// context and current thread.
    /// </summary>
    public class MultilevelPrincipalBuilder
    {
        private readonly HttpContextBase _context;
        private readonly MultilevelPrincipal _principal;

        /// <summary>
        /// Initializes a new instance of the <see cref="MultilevelPrincipalBuilder"/> class.
        /// </summary>
        /// <param name="context">Http context to build principal for.</param>
        public MultilevelPrincipalBuilder(HttpContextBase context)
        {
            _context = context;
            if (_context.User is MultilevelPrincipal)
                _principal = (MultilevelPrincipal)_context.User;
            else
            {
                _principal = new MultilevelPrincipal();
                _context.User = _principal;
            }

            Thread.CurrentPrincipal = _principal;
        }

        /// <summary>
        /// Assigns new identity to the current principal using the specified details.
        /// </summary>
        /// <param name="username">Name of the identified user.</param>
        /// <param name="type">Type of the identity to assign.</param>
        /// <exception cref="System.Security.SecurityException">
        /// Indicates that the specified type is not supported.
        /// </exception>
        public void AssignIdentity(string username, UserTypes type)
        {
            switch (type)
            {
                case UserTypes.Administrator:
                    _principal.AdministratorIdentity = new WebIdentity(username, true);
                    break;
                case UserTypes.SysAdmin:
                    _principal.SystemIdentity = new WebIdentity(username, true);
                    break;
                case UserTypes.EndUser:
                    _principal.Identity = new WebIdentity(username, true);
                    break;
                default:
                    throw new SecurityException("Unrecognized user type: " + type);
            }
        }

        /// <summary>
        /// Assigns the specified roles to the end user identity of the current principal.
        /// </summary>
        /// <param name="roles">The roles to assign.</param>
        public void AssignRoles(UserRoles roles)
        {
            _principal.Roles = roles;
        }
    }
}